import { Injectable, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DataSource } from 'typeorm';
import { VoucherUsageLog } from './entities/voucher-usage-log.entity';
import { UnlockResourceDto } from './dto/unlock-resource.dto';
import { WalletService } from '../wallet/wallet.service';

/**
 * 代金券服务
 */
@Injectable()
export class VoucherService {
  constructor(
    @InjectRepository(VoucherUsageLog)
    private readonly voucherUsageLogRepository: Repository<VoucherUsageLog>,
    private readonly walletService: WalletService,
    private readonly dataSource: DataSource,
  ) {}

  /**
   * 使用代金券解锁资源
   */
  async unlockResource(userId: number, unlockDto: UnlockResourceDto): Promise<VoucherUsageLog> {
    const { amountUsed, resourceType, resourceId, resourceName, description } = unlockDto;
    
    // 检查用户代金券余额
    const wallet = await this.walletService.getWallet(userId);
    if (wallet.voucherBalance < amountUsed) {
      throw new BadRequestException('代金券余额不足');
    }
    
    return await this.dataSource.transaction(async (manager) => {
      // 扣除代金券余额
      await this.walletService.deductVoucherBalance(userId, amountUsed);
      
      // 记录使用日志
      const usageLog = this.voucherUsageLogRepository.create({
        userId,
        amountUsed,
        resourceType,
        resourceId,
        resourceName,
        description,
      });
      
      return await manager.save(VoucherUsageLog, usageLog);
    });
  }

  /**
   * 获取用户代金券使用记录
   */
  async getUserUsageHistory(userId: number, page = 1, limit = 10): Promise<{
    data: VoucherUsageLog[];
    total: number;
    page: number;
    limit: number;
  }> {
    const [data, total] = await this.voucherUsageLogRepository.findAndCount({
      where: { userId },
      order: { createdAt: 'DESC' },
      skip: (page - 1) * limit,
      take: limit,
    });
    
    return { data, total, page, limit };
  }

  /**
   * 获取用户在特定资源类型上的使用记录
   */
  async getUserUsageByResourceType(
    userId: number,
    resourceType: string,
    page = 1,
    limit = 10,
  ): Promise<{
    data: VoucherUsageLog[];
    total: number;
    page: number;
    limit: number;
  }> {
    const [data, total] = await this.voucherUsageLogRepository.findAndCount({
      where: { userId, resourceType },
      order: { createdAt: 'DESC' },
      skip: (page - 1) * limit,
      take: limit,
    });
    
    return { data, total, page, limit };
  }

  /**
   * 检查用户是否已解锁特定资源
   */
  async hasUnlockedResource(userId: number, resourceType: string, resourceId?: number): Promise<boolean> {
    const whereCondition: any = { userId, resourceType };
    if (resourceId !== undefined) {
      whereCondition.resourceId = resourceId;
    }
    
    const count = await this.voucherUsageLogRepository.count({
      where: whereCondition,
    });
    
    return count > 0;
  }

  /**
   * 获取用户在特定资源类型上的总消费
   */
  async getUserTotalSpentOnResourceType(userId: number, resourceType: string): Promise<number> {
    const result = await this.voucherUsageLogRepository
      .createQueryBuilder('log')
      .select('SUM(log.amountUsed)', 'total')
      .where('log.userId = :userId', { userId })
      .andWhere('log.resourceType = :resourceType', { resourceType })
      .getRawOne();
    
    return parseInt(result.total) || 0;
  }

  /**
   * 管理员获取所有代金券使用记录
   */
  async getAllUsageHistory(page = 1, limit = 10): Promise<{
    data: VoucherUsageLog[];
    total: number;
    page: number;
    limit: number;
  }> {
    const [data, total] = await this.voucherUsageLogRepository.findAndCount({
      relations: ['user'],
      order: { createdAt: 'DESC' },
      skip: (page - 1) * limit,
      take: limit,
    });
    
    return { data, total, page, limit };
  }

  /**
   * 获取代金券使用统计
   */
  async getUsageStatistics(): Promise<{
    totalUsage: number;
    totalAmount: number;
    resourceTypeStats: Array<{ resourceType: string; count: number; totalAmount: number }>;
  }> {
    // 总使用次数和总金额
    const totalStats = await this.voucherUsageLogRepository
      .createQueryBuilder('log')
      .select('COUNT(*)', 'totalUsage')
      .addSelect('SUM(log.amountUsed)', 'totalAmount')
      .getRawOne();
    
    // 按资源类型统计
    const resourceTypeStats = await this.voucherUsageLogRepository
      .createQueryBuilder('log')
      .select('log.resourceType', 'resourceType')
      .addSelect('COUNT(*)', 'count')
      .addSelect('SUM(log.amountUsed)', 'totalAmount')
      .groupBy('log.resourceType')
      .getRawMany();
    
    return {
      totalUsage: parseInt(totalStats.totalUsage) || 0,
      totalAmount: parseInt(totalStats.totalAmount) || 0,
      resourceTypeStats: resourceTypeStats.map(stat => ({
        resourceType: stat.resourceType,
        count: parseInt(stat.count),
        totalAmount: parseInt(stat.totalAmount),
      })),
    };
  }
}